#include "app_dp_set.h"

#define ARRAY_DATA_TO_UINT32(dat)  (dat[0] << 24 | dat[1] << 16 | dat[2] << 8 | dat[3])
#define ARRAY_DATA_TO_UINT16(dat)  (dat[0] << 8 | dat[1])
#define DPID_VALUE_LENGTH_ITEM_SIZE 2

static void app_dp_set_meal_plan(const unsigned char *data, unsigned short length)
{
    ret_if_true(NULL == data || 0 == length)
    if (length >= USER_FLASH_DATA_SIZE) {
        return ;
    }

    app_plan_set(data, length);
    app_dp_meal_plan_notify();
}

static void app_dp_set_manual_feed(unsigned int value)
{
    dp_obj->value = value & 0xFF;
    app_release_set_value(dp_obj->value);
    app_dp_manual_feed_notify();
}


static void app_dp_set_handler(dp_obj_t *obj)
{
    switch (obj->dpid) {
        case DP_MEAL_PLAN: {
            app_dp_set_meal_plan(obj->value.raw, obj->length);
            break;
        }
        case DP_MANUAL_FEED: {
            app_dp_set_manual_feed(obj->value.number);
            break;
        }
        default:
            break;
    }
}

void app_dp_set_cb_handler(const unsigned char *data, unsigned short length)
{
    ret_if_true(NULL == data || 0 == length);

    dp_obj_t dp_obj = {0x00};
    unsigned char offset = 0;

    while ((offset + 4) < length) {
        memset((void *)&dp_obj, 0x00, sizeof(dp_obj_t));

        dp_obj.dpid     = data[offset++];
        dp_obj.type     = data[offset++];
        dp_obj.length   = ARRAY_DATA_TO_UINT16((data+offset));
        offset          += DPID_VALUE_LENGTH_ITEM_SIZE;

        switch (dp_obj.type) {
            case DP_TYPE_RAW: 
                dp_obj.value.raw = &data[offset];
                break;
            case DP_TYPE_BOOL:
                dp_obj.value.boolean = data[offset];
                break;
            case DP_TYPE_NUMBER: 
                dp_obj.value.number = ARRAY_DATA_TO_UINT32((data+offset));
                break;
            case DP_TYPE_STRING:
                dp_obj.value.string = (const char *)&data[offset];
                break;
            case DP_TYPE_ENUM:
                dp_obj.value.enumeration = data[offset];
                break;
            case DP_TYPE_BITMAP:
                dp_obj.value.bitmap = ARRAY_DATA_TO_UINT32((data+offset));
                break;
            default:
                return ;
        }

        offset += dp_obj.length;
        app_dp_set_handler(&dp_obj);
    }
}